package ift604.projet;

import static ift604.projet.feeling.Feeling.getFeelingFromName;
import static ift604.projet.feeling.FeelingWithPosition.associateFeelingWithGeoPosition;
import static ift604.projet.music.MusicPlayer.displayConnectWithStereoMood;
import static ift604.projet.music.MusicPlayer.displayLoadingOnMusicPlayer;
import static ift604.projet.music.MusicPlayer.displayMusicPlayer;
import static ift604.projet.utils.GeoPosition.currentGeoPosition;
import ift604.projet.feeling.Feeling;
import ift604.projet.feeling.FeelingListActivity;
import ift604.projet.feeling.FeelingSelectionActivity;
import ift604.projet.feeling.UserFeelingUpdatedListener;
import ift604.projet.music.Playlist;
import ift604.projet.music.PlaylistUpdatedListener;
import ift604.projet.stereomood.StereoMoodAPI;
import ift604.projet.utils.GeoPosition;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;

public class MapMyFeelingsActivity extends MapActivity implements UserFeelingUpdatedListener, PlaylistUpdatedListener {

	public static final int EMOTION_SELECTION_REQUEST = 1;
	public static final int SONG_SELECTION_REQUEST = 2;
	public MyLocationOverlay myPos;

	MapMyFeelingsApplication mapMyFeelingsApplication;

	public StereoMoodAPI stereoMoodAPI;
	boolean centrerSurGPS;


	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.main_menu);

		showSplashScreen();
		removeSplashScreenAfterSomeTime();

		mapMyFeelingsApplication = (MapMyFeelingsApplication) getApplication();
		mapMyFeelingsApplication.addUpdateFeelingListener(this);
		mapMyFeelingsApplication.mapMyFeelingsActivity = this;

		configureGoogleMapAPI();

		stereoMoodAPI = new StereoMoodAPI(this);

		stereoMoodAPI.addPlayListUpdatedListener(this);
		stereoMoodAPI.addPlayListUpdatedListener(mapMyFeelingsApplication);



		RelativeLayout seeFeelings = (RelativeLayout) findViewById(R.id.menuItemList);
		seeFeelings.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent feelingsList = new Intent(getBaseContext(), FeelingListActivity.class);
				startActivity(feelingsList);
			}
		});


		RelativeLayout sayHowYouFeelButton = (RelativeLayout) findViewById(R.id.menuItemAdd);
		sayHowYouFeelButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent feelingSelection = new Intent(getBaseContext(), FeelingSelectionActivity.class);
				startActivityForResult(feelingSelection, EMOTION_SELECTION_REQUEST);
			}
		});

		// pour updater les checkins a chaque intervalle de temps
		startService( new Intent(this, UpdaterService.class) ); 
	}

	private void showSplashScreen(){
		FrameLayout mainMenu = (FrameLayout) findViewById(R.id.main_menu_layout);
		LinearLayout splashScreen = (LinearLayout) findViewById(R.id.splash_screen);
		mainMenu.bringChildToFront(splashScreen);
	}

	private void removeSplashScreenAfterSomeTime(){
		final Animation toDisappearance = AnimationUtils.loadAnimation(this, R.anim.alpha);
		toDisappearance.reset();
		LinearLayout splashScreen = (LinearLayout) findViewById(R.id.splash_screen);
		splashScreen.startAnimation(toDisappearance);

		toDisappearance.setAnimationListener(new Animation.AnimationListener() {
			@Override
			public void onAnimationStart(Animation animation) {
				//To change body of implemented methods use File | Settings | File Templates.
			}

			@Override
			public void onAnimationEnd(Animation animation) {
				LinearLayout splashScreen = (LinearLayout) findViewById(R.id.splash_screen);
				splashScreen.setVisibility(View.GONE);
			}

			@Override
			public void onAnimationRepeat(Animation animation) {
				//To change body of implemented methods use File | Settings | File Templates.
			}
		});
	}

	private void configureGoogleMapAPI() {

		MapView mapView = (MapView) findViewById(R.id.mapview);

		final MapController mapController = mapView.getController();

		myPos = new MyLocationOverlay(this, mapView);
		myPos.enableMyLocation();
		// add this overlay to the MapView and refresh it
		mapView.getOverlays().add(myPos);
		mapView.postInvalidate();

		// Default
		GeoPoint myGeo = new GeoPoint(45379282, -71928799); // centre sur l'universite par default
		mapController.setZoom(14);
		mapController.setCenter(myGeo);

		// When GPS has a fix
		myPos.runOnFirstFix(new Runnable() {
			public void run() {
				mapController.animateTo(myPos.getMyLocation());
			}
		});

		// Acquire a reference to the system Location Manager
		LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

		// Define a listener that responds to location updates
		LocationListener locationListener = new LocationListener() {    
			public void onLocationChanged(Location location) {
				if (centrerSurGPS) {
					mapController.animateTo(GeoPosition.locationToGeoPoint(location));
				}
			}    
			public void onStatusChanged(String provider, int status, Bundle extras) {}
			public void onProviderEnabled(String provider) {}
			public void onProviderDisabled(String provider) {}  
		};

		// Register the listener with the Location Manager to receive location updates
		locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
	}

	public MyLocationOverlay getMyPos() {
		return myPos;
	}

	@Override
	// when our activity resumes, we want to register for location updates
	protected void onResume() {
		super.onResume();
		myPos.enableMyLocation();
	}

	@Override
	// when our activity pauses, we want to remove listening for location updates
	protected void onPause() {
		super.onPause();
		myPos.disableMyLocation();
	}

	public void onActivityResult(int requestCode, int resultCode, Intent data){
		if (resultCode != RESULT_OK){
			return;
		}

		switch(requestCode){
		case EMOTION_SELECTION_REQUEST :
			String feelingNameOnUserInterface = data.getData().toString();
			mapMyFeelingsApplication.currentUserFeeling(getFeelingFromName(feelingNameOnUserInterface));
		}
	}

	private void buildPlaylistFromFeeling(Feeling feeling){
		stereoMoodAPI.buildPlaylistOfFeeling(feeling);
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	@Override
	public void feelingOfUserUpdated(Feeling feeling) {
		displayConnectWithStereoMood(this);
		findViewById(R.id.getPlaylist).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				Activity mapMyFeelingsActivity = (Activity) view.getContext();
				buildPlaylistFromFeeling(mapMyFeelingsApplication.currentUserFeeling());
				displayLoadingOnMusicPlayer(mapMyFeelingsActivity);
			}
		});
		associateFeelingWithGeoPosition(this, feeling, currentGeoPosition(this));
		mapMyFeelingsApplication.updaterService.updateMapCheckins();

	}

	@Override
	public void playlistUpdated(final Playlist playlist) {
		playlist.playRandomSong();
		runOnUiThread(new Runnable() {
			public void run() {
				displayMusicPlayer(MapMyFeelingsActivity.this, playlist);
			}
		});
	}

	@Override
	public void playlistUpdateFailed() {
		final Playlist playlist = mapMyFeelingsApplication.sqlPlaylistRepository.getCachePlaylist(mapMyFeelingsApplication.currentUserFeeling);
		mapMyFeelingsApplication.currentPlaylist = playlist;

		playlist.playRandomSong();
		runOnUiThread(new Runnable() {
			public void run() {
				displayMusicPlayer(MapMyFeelingsActivity.this, playlist);
			}
		});
	}

	// Called first time user clicks on the menu button
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();   
		inflater.inflate(R.menu.menu, menu);         
		return true; 
	}
	// Called when an options item is clicked
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {                              
		case R.id.itemPrefs:
			startActivity(new Intent(this, PrefsActivity.class));   
			break;
		}
		return true;  
	}

}